package com.juyu.miliao.api.service;

import com.juyu.miliao.api.dao.mysql.*;
import com.juyu.miliao.api.dao.redis.SmsSenderRedisDao;
import com.juyu.miliao.api.dao.redis.UserAuthenticationInfoRedisDao;
import com.juyu.miliao.api.domain.*;
import com.juyu.miliao.api.domain.dto.UserAuthenticationDTO;
import com.juyu.miliao.api.domain.vo.CheckUserAutenticationVO;
import com.juyu.miliao.common.domain.CommonHead;
import com.juyu.miliao.common.domain.ConfigSms;
import com.juyu.miliao.common.exception.ConsumeRuntimeException;
import com.juyu.miliao.common.security.exception.WrongUserNameException;
import com.juyu.miliao.common.util.CommonUtil;
import com.juyu.miliao.common.util.SmsSender;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;


/**
 * @author xuanqicheng
 * @create 2019-17-10:31
 */
@Service
public class UserAuthenticationInfoService {

    @Autowired
    private UserAuthenticationInfoDao userAuthenticationInfoDao;

    @Autowired
    private UserAuthenticationInfoRedisDao userAuthenticationInfoRedisDao;

    @Autowired
    private UserLoginDao userLoginDao;

    @Autowired
    private UserInfoDao userInfoDao;

    @Resource
    private SmsSenderRedisDao smsSenderRedisDao;

    @Resource
    private ConfigSmsDao configSmsDao;

    @Resource
    private UserWalletDao userWalletDao;
    @Resource
    private BillDetailDao billDetailDao;
    @Resource
    private AppKeyService appKeyService;
    /**
     * 检查用户认证信息
     *
     * @param userId
     * @return
     */
    public CheckUserAutenticationVO checkUserAutenticationInfo(long userId) {

        CheckUserAutenticationVO checkUserAutenticationVO = new CheckUserAutenticationVO();

        UserAuthenticationInfo checkInfo = userAuthenticationInfoDao.checkUserAutenticationByUserId(userId);


        if (checkInfo == null) {
            /**
             * 用户没有绑定手机
             */
            checkUserAutenticationVO
                    .setCode(1001)
                    .setMessage("用户没有进行认证");

            return checkUserAutenticationVO;


        } else if (checkInfo.getStatus() == 0) {
            /**
             * 用户可以认证
             */
            checkUserAutenticationVO
                    .setCode(1000)
                    .setMessage("用户没有认证，可以开始认证");

            return checkUserAutenticationVO;

        } else if (checkInfo.getStatus() == 1) {
            /**
             * 用户认证正在审批
             */
            checkUserAutenticationVO
                    .setCode(1002)
                    .setMessage("用户认证正在审批中，请稍等");
            return checkUserAutenticationVO;

        } else if (checkInfo.getStatus() == 2) {
            /**
             * 用户认证成功通过，无需认证
             */
            checkUserAutenticationVO
                    .setCode(1003)
                    .setMessage("用户已经认证成功，请勿重复认证");
            return checkUserAutenticationVO;
        } else {
            /**
             * 用户认证失败，请重新认证
             */
            checkUserAutenticationVO
                    .setCode(1004).setMessage("用户认证失败，请重新认证");
            return checkUserAutenticationVO;
        }
    }

    /**
     * @param userId
     * @param phone
     * @param validateCode
     */
    public void sendPhoneNumValidateCode(long userId, String phone, String validateCode, CommonHead com) {

        checkPhoneIsBinding(userId, phone);
        if (smsSenderRedisDao.isMemberBlacklist(phone)) {
            throw new ConsumeRuntimeException("手机号异常");
        }
        if (smsSenderRedisDao.isMember(phone)) {
            throw new ConsumeRuntimeException("手机号1分钟内不能重复发送短信");
        }
//        Double score = smsSenderRedisDao.scoreSmsSenderEveryDay(phone);
//        if(score != null && score > 10){
//            throw new ConsumeRuntimeException("该手机号发送数量受限");
//        }
        //发送短信
//        SmsSender smsSender = new SmsSender(phone,"绑定验证码"+validateCode+"，十分钟内有效，请尽快完成绑定。");
        SmsSender smsSender = new SmsSender(phone, 349689, validateCode);
        smsSender.sendSms(com, getConfigSmsSing(com));
        smsSenderRedisDao.addSmsSender(phone);
        userAuthenticationInfoRedisDao.sendPhoneNumVerificationCode(phone, validateCode, 10);
//        smsSenderRedisDao.addSmsSenderByEveryDay(phone);
    }

    private String getConfigSmsSing(CommonHead com) {
        List<ConfigSms> configSmsList = configSmsDao.listConfigSms();
        String sign = "";
        String huamiSign = "";
        for (ConfigSms c : configSmsList) {
            if (c.getAppPackageId().equals("huami")) {
                huamiSign = c.getSignId();
            }
            if (c.getAppPackageId().equals(com.getAppPackageId())) {
                sign = c.getSignId();
            }
        }
        if (sign.equals(""))
            sign = huamiSign;
        return sign;
    }

    /**
     * @param userId
     * @param phone
     * @param validateCode
     */
    public void sendPhoneNumValidate(long userId, String phone, String validateCode, CommonHead com) {

        if (smsSenderRedisDao.isMemberBlacklist(phone)) {
            throw new ConsumeRuntimeException("手机号异常");
        }
        if (smsSenderRedisDao.isMember(phone)) {
            throw new ConsumeRuntimeException("手机号1分钟内不能重复发送短信");
        }
//        Double score = smsSenderRedisDao.scoreSmsSenderEveryDay(phone);
//        if(score != null && score > 10){
//            throw new ConsumeRuntimeException("该手机号发送数量受限");
//        }
        userAuthenticationInfoRedisDao.sendPhoneNumVerificationCode(phone, validateCode, 10);
        //发送短信 TODO 发送短信模板未添加
//        SmsSender smsSender = new SmsSender(phone,"绑定验证码"+validateCode+"，十分钟内有效，请尽快完成绑定。");
        SmsSender smsSender = new SmsSender(phone, 349689, validateCode);
        smsSender.sendSms(com, getConfigSmsSing(com));
        smsSenderRedisDao.addSmsSender(phone);
//        smsSenderRedisDao.addSmsSenderByEveryDay(phone);
    }

    /**
     * 绑定手机号
     *
     * @param userAuthenticationDTO
     */
    public void bindingPhone(UserAuthenticationDTO userAuthenticationDTO, int isHost) {

        String code = userAuthenticationInfoRedisDao.getPhoneNumVerificationCode(userAuthenticationDTO.getPhone());

        if (StringUtils.isEmpty(code)) {
            throw new ConsumeRuntimeException("验证码过期");
        }

        if (!code.equals(userAuthenticationDTO.getCode())) {
            throw new ConsumeRuntimeException("验证码不正确,请重新填写");
        }

        checkPhoneIsBinding(userAuthenticationDTO.getUserId(), userAuthenticationDTO.getPhone());


        UserAuthenticationInfo entity = new UserAuthenticationInfo();

        BeanUtils.copyProperties(userAuthenticationDTO, entity);

//        UserAuthenticationInfo obj = userAuthenticationInfoDao
//                .checkUserAutenticationByUserId(userAuthenticationDTO.getUserId());
//
//        if(obj !=null){
//            throw new ConsumeRuntimeException("此账号已经绑定过手机号，请勿重复绑定");
//        }
        entity.setStatus(0);

        Optional<Integer> userIdByUserName = userAuthenticationInfoRedisDao
                .getUserIdByUserName(userAuthenticationDTO.getPhone());
        if (userIdByUserName.isPresent()) {
            throw new ConsumeRuntimeException("该手机已被注册，请勿重复绑定");
        }
//        userAuthenticationInfoDao.bindingPhone(entity);
        userLoginDao.updateUserLoginUserNameAndPassWord(userAuthenticationDTO.getUserId()
                , userAuthenticationDTO.getPhone(), "a" + (int) ((Math.random() * 9 + 1) * 100000));
        userAuthenticationInfoRedisDao.addUserName(userAuthenticationDTO.getPhone(), userAuthenticationDTO.getUserId());
        //1.5.6新用户注册送金币
        if(userAuthenticationInfoRedisDao.isMemberNewUserBinding(userAuthenticationDTO.getUserId())){
            //加金币
            UserWallet userWallet = new UserWallet();
            userWallet.setUserId(userAuthenticationDTO.getUserId());
            Appkey appkey = appKeyService.getAppKeyByKey("newUserBindingPhoneGiftDeposit");
            if(appkey==null)
                throw new ConsumeRuntimeException("配置参数错误：newUserBindingPhoneGiftDeposit");
            userWallet.setDeposit(Integer.parseInt(appkey.getValue()));
            userWalletDao.reviseDeposit(userWallet);
            //加账单
            BillDetailDeposit billDetailDeposit = new BillDetailDeposit();
            billDetailDeposit.setRecordType(15);
            billDetailDeposit.setInUserId(userAuthenticationDTO.getUserId());
            billDetailDeposit.setOutUserId(0);
            billDetailDeposit.setSpend(Integer.parseInt(appkey.getValue()));
            billDetailDeposit.setDiamond(0);
            billDetailDeposit.setRatio(0);
            billDetailDao.insertBillDetailDeposit(billDetailDeposit);
            //去掉redis数据
            userAuthenticationInfoRedisDao.removeNewUserBinding(userAuthenticationDTO.getUserId());
        }
    }

    /**
     * 检查手机号是否注册或绑定过
     *
     * @param phone
     */
    private void checkPhoneIsBinding(long userId, String phone) {
        List<String> list = userLoginDao.selectPhone(userId, phone);
        if (list.size() > 0) {
            throw new ConsumeRuntimeException("该手机号已注册");
        }

        List<String> phoneList = userAuthenticationInfoDao.selectUserAuthenticationByPhone(phone);

        if (phoneList.size() > 0) {
            throw new ConsumeRuntimeException("该手机号已绑定");
        }
    }

    public void bindingUser(UserAuthenticationDTO userAuthenticationDTO) {

        User userInfo = userInfoDao.getUserById(userAuthenticationDTO.getUserId());

        if (userInfo.getIsHost() == 1) {
            throw new ConsumeRuntimeException("此用户已经是主播，不能重复认证");
        }

//        List<Long> list = CommonUtil.changeIds(userAuthenticationDTO.getTags());
//        if (list.isEmpty() || list.size() > 3) {
//            throw new ConsumeRuntimeException("标签不能为空且不大于3个");
//        }

        UserAuthenticationInfo entity = new UserAuthenticationInfo();

        BeanUtils.copyProperties(userAuthenticationDTO, entity);

        UserAuthenticationInfo obj = userAuthenticationInfoDao.getUserAuthenticationByUserId(entity.getUserId());

        if (obj == null) {
            String userName = userLoginDao.getPhoneByUserId(userInfo.getUserId());
            entity.setPhone(userName);
            userAuthenticationInfoDao.insertInfo(entity);
//            labelService.insertLabelForUserMeLabel(entity.getUserId(),list);
            updateUserStatus(entity);

        } else {
            if (obj.getStatus() == 1) {

                /**
                 * 用户认证正在审批中
                 */
                throw new ConsumeRuntimeException("用户认证正在审批中，请稍等！");
            } else if (obj.getStatus() == 2) {
                /**
                 * 用户认证成功通过，无需认证
                 */
                throw new ConsumeRuntimeException("用户已经认证过，请勿重复认证");
            } else {
                userAuthenticationInfoDao.bindingUser(entity);
//                labelService.insertLabelForUserMeLabel(entity.getUserId(),list);
                updateUserStatus(entity);

            }
        }


    }

    /**
     * 更改用户状态
     *
     * @param entity
     */
    private void updateUserStatus(UserAuthenticationInfo entity) {
        User user = new User();

        user.setIsCertificationHost(3);

        user.setUserId(entity.getUserId());

        userInfoDao.updateUserCertificationHost(user);
    }

    /**
     * 根据用户id，查看用户认证信息
     *
     * @param userId
     * @return
     */
    public UserAuthenticationInfo getUserAuthenticationInfoByUserId(long userId) {
        UserAuthenticationInfo obj = userAuthenticationInfoDao.getUserAuthenticationByUserId(userId);
        return obj;
    }

    public Map<String, String> getPhone(long id) {
        UserAuthenticationInfo obj = userAuthenticationInfoDao.getBindingPhoneByUserId(id);
        if (obj != null && !StringUtils.isEmpty(obj.getPhone())) {
            Map<String, String> map = new HashMap<>(1);

            String temp = "+86-" + obj.getPhone().substring(0, 4) + "****" + obj.getPhone().substring(8, 11);
            map.put("phone", temp);
            map.put("tel", obj.getPhone());
            return map;
        } else {
            return new HashMap<>(0);
        }
    }
}
